//
//  ZZXDecryptVC.m
//  Created  on 2022/7/11.
//

#import "ZZXDecryptVC.h"
#import "ZZXDragTV.h"

#include "string"
#include <iostream>

@interface ZZXDecryptVC ()
<NSTableViewDelegate,
NSTableViewDataSource,
ZZXDragTVDelegate>

@property (weak) IBOutlet ZZXDragTV *dragTV;

@property (unsafe_unretained) IBOutlet NSTextView *logTV;
@property (nonatomic,strong) NSMutableString* logStr;

@property (nonatomic,strong) NSOpenPanel* openPanel;
@property (nonatomic,strong) NSMutableArray* selectFileArr;
@property (nonatomic,strong) NSString* originalFilePath;
@property (nonatomic,strong) NSString* targetFilePath;

@end

@implementation ZZXDecryptVC

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self _initSubview];
    [self _initTableView];
}

#pragma mark - init
-(void)_initSubview{
    self.logStr = [NSMutableString stringWithFormat:@"Terminal"];
    self.logTV.string = self.logStr;
    self.selectFileArr = [NSMutableArray arrayWithCapacity:0];
    
    //[self __];
}
-(void)_initTableView{
    self.dragTV.delegate = self;
    self.dragTV.dataSource = self;
    self.dragTV.dragDelegate = self;
    self.dragTV.allowsMultipleSelection = YES;
    self.dragTV.allowsColumnSelection = NO;
}

#pragma mark - 选择文件、文件夹
- (IBAction)selecBtnClick:(id)sender {
    
    NSWindow *window = [NSApplication sharedApplication].keyWindow;
    
    NSOpenPanel *openPanel = [NSOpenPanel openPanel];
    [openPanel setPrompt: @"打开"];
    
    openPanel.canChooseFiles = YES;
    openPanel.canChooseDirectories = YES;
    openPanel.canCreateDirectories = NO;
    openPanel.allowsMultipleSelection = YES;
    
    //openPanel.allowedFileTypes = [NSArray arrayWithObjects: @"docx",@"doc",@"txt",@"xls",@"xlsx",@"ppt",@"pptx",@"pdf",@"jpeg",@"jpg",@"bmp",@"png",@"tif",@"gif",@"tiff",@"zip",@"7z",@"rar",@"cc",@"h",@"m",@"cpp",@"mm", nil];
    openPanel.directoryURL = nil;
    self.openPanel  = openPanel;
    [self.openPanel beginSheetModalForWindow:window completionHandler:^(NSModalResponse result) {
        if (result == NSModalResponseOK) {
            
            NSArray *urlArr = [self.openPanel URLs];
            for (NSURL *pathUrl in urlArr) {
                NSString *filePath = pathUrl.path;
                [self.selectFileArr addObject:filePath];
            }
            [self.dragTV reloadData];
        }
    }];
    
}
#pragma mark - 移除文件
- (IBAction)removeFileClick:(id)sender {
    
    if (self.dragTV.selectedRowIndexes.count <= 0) {
        return;
    }
    NSIndexSet *selectedRowIndexes = self.dragTV.selectedRowIndexes;
    
    NSMutableArray *tempArr = [NSMutableArray arrayWithArray:self.selectFileArr];
    [selectedRowIndexes enumerateRangesUsingBlock:^(NSRange range, BOOL * _Nonnull stop) {
        NSUInteger selectedRow = range.location;
        NSURL *fileUrl = self.selectFileArr[selectedRow];
        [tempArr removeObject:fileUrl];
        
        [self writeLogStr:[NSString stringWithFormat:@"移除：%@",fileUrl.lastPathComponent]];
    }];
    self.selectFileArr = [NSMutableArray arrayWithArray:tempArr];
    [self.dragTV reloadData];
}
- (IBAction)removeAllFileClick:(id)sender {
    
    [self.selectFileArr removeAllObjects];
    [self.dragTV reloadData];
    [self writeLogStr:@"删除全部选择的文件！"];
}

//MARK: - install_name_tool
- (IBAction)install_name_tool_id:(id)sender {
    
    [self executionSelectArray:11];
}
- (IBAction)install_name_tool_change:(id)sender {
    
    [self executionSelectArray:12];
}

/// 修改第三方dylib的Install_name
void execute_install_name_tool(scan_info *data){
    std::string  file_name = data->file_name;
    std::string  file_path = data->file_path;
    
    std::string commands = nullptr;
    
    switch (data->action_type) {
        case 11:{
            commands = "install_name_tool -id @rpath/" + file_name + " " + file_path;
            
            }   break;
        case 12:{
            //  install_name_tool -change /Users/ipguard02/docwire/vcpkg/installed/arm64-osx-dynamic/lib/libcrypto.3.dylib @executable_path/../Frameworks/libcrypto.3.dylib /Users/ipguard02/Zzx/DocFile/DocwireTestLib/DocwireTestLib/lib/ossl-modules/legacy.dylib
            //commands = "install_name_tool -change " + file_name + " " + file_path;
            }   break;
        default:
            break;
    }
    std::cout << "commands: " << commands << std::endl;
    
    system(commands.c_str());
    
}

//MARK: - otool -L
- (IBAction)otool_L_Click:(id)sender {
    
    [self executionSelectArray:21];
}
//MARK: - otool -l
- (IBAction)otool_l_Click:(id)sender {
    
    [self executionSelectArray:22];
}

void execute_otool(scan_info *data){
    std::string  file_name = data->file_name;
    std::string  file_path = data->file_path;
    
    std::string commands = "";
    
    switch (data->action_type) {
        case 21:{
            commands = "otool -L " + file_path;
            
            }   break;
        case 22:{
            commands = "otool -l " + file_path;
            }   break;
        default:
            break;
    }
    std::cout << "commands: " << commands << std::endl;
    
    system(commands.c_str());
}

//MARK: - Execution Select Array
-(void)executionSelectArray:(int )type{
    
    if (self.selectFileArr.count <= 0) {
        [self writeLogStr:@"请选择文件/文件夹路径！"];
        return;
    }

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
        scan_info tempdata;
        memset(&tempdata, 0, sizeof(scan_info));
        tempdata.action_type = type;
        tempdata.server_type = 1;
        tempdata.file_type = 1;
        
        // 耗时的操作
        for (NSString *tempPath in self.selectFileArr) {

            std::string filename = tempPath.lastPathComponent.UTF8String;
            std::string filepath = tempPath.UTF8String;
            
            strcpy(tempdata.file_name, filename.c_str());
            strcpy(tempdata.file_path, filepath.c_str());
            
            if (is_directory(filepath)) {
                scan_folder(&tempdata);
            } else {
                execute_file(&tempdata);
            }
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            
        });
    });
    
}

#include <filesystem>
namespace fs = std::filesystem;

// 是否是文件夹
bool is_directory(const std::string& path) {
    return fs::exists(path) && fs::is_directory(path);
}

bool contains(const std::string& haystack, const std::string& needle) {
    return haystack.find(needle) != std::string::npos;
}
bool is_dylib(const std::string& path) {
    
    std::string str = path;
    std::string substr = "dylib";
    
    if (contains(str, substr)) {
        return YES;
    } else {
        std::cout << "字符串 \"" << str << "\" 不包含 \"" << substr << "\"." << std::endl;
        return NO;
    }
}
/// 遍历文件夹
void scan_folder(scan_info *data){
    
    const fs::path pathToFolder = data->file_path; // 替换为你的文件夹路径
    for (const auto& entry : fs::recursive_directory_iterator(pathToFolder)) {
        
        if (entry.is_regular_file()) {
            const auto filenameStr  = entry.path().filename().string();
            std::string filetype    = entry.path().extension().string();
            std::string filePathStr = entry.path().string();
            
            strcpy(data->file_name, filenameStr.c_str());
            strcpy(data->file_path, filePathStr.c_str());
            
            execute_file(data);
        } else if (entry.is_directory()) {
            //std::cout << "Found directory: " << filenameStr << std::endl;
        }
    }
}
/// 处理文件
void execute_file(scan_info *data){
    
    switch (data->action_type) {
        case 11:
        case 12:{
            execute_install_name_tool(data);
            }   break;
        case 21:
        case 22:{
            execute_otool(data);
            }   break;
        default:
            break;
    }
}


#pragma mark - 日志
-(void)writeLogStr:(NSString *)logStr{
    
    NSDateFormatter *df = [[NSDateFormatter alloc] init];
    df.dateFormat = @"yyyy-MM-dd hh:mm:ss";
    NSString *today = [df stringFromDate:[NSDate date]];
    NSString *str = [NSString stringWithFormat:@"%@:%@",today,logStr];
    [self.logStr insertString:@"\n" atIndex:0];
    [self.logStr insertString:str atIndex:0];
    self.logTV.string = self.logStr;
    
}
void currentTime(char *value){
    time_t timep;
    struct tm *p;
    
    time (&timep);
    p=gmtime(&timep);
    //将它们合成一个字符串
    sprintf(value,"%d-%d-%d %d:%d:%d",1900+p->tm_year,1+p->tm_mon,p->tm_mday,8+p->tm_hour,p->tm_min,p->tm_sec);
    
    /*
     printf("%d\t",p->tm_sec); //获取当前秒
     printf("%d\t",p->tm_min); //获取当前分
     printf("%d\t",8+p->tm_hour);//获取当前时,这里获取西方的时间,刚好相差八个小时
     printf("%d\t",p->tm_mday);//获取当前月份日数,范围是1-31
     printf("%d\t",1+p->tm_mon);//获取当前月份,范围是0-11,所以要加1
     printf("%d\t",1900+p->tm_year);//获取当前年份,从1900开始，所以要加1900
     printf("%d\n",p->tm_yday); //从今年1月1日算起至今的天数，范围为0-365
     */
}


-(void)__{
    NSDateFormatter *df = [[NSDateFormatter alloc] init];
    df.dateFormat = @"yyyy-MM-dd HH:mm:ss";
    NSString *today = [df stringFromDate:[NSDate date]];
    
    NSDateFormatter *date = [[NSDateFormatter alloc]init];
    [date setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSDate *startD =[date dateFromString:@"2024-05-11 00:00:00"];
    NSDate *endD = [date dateFromString:today];
    NSTimeInterval start = [startD timeIntervalSince1970] * 1;
    NSTimeInterval end = [endD timeIntervalSince1970] * 1;
    NSTimeInterval value = end - start;
    NSInteger second = (NSInteger )value;//秒
    
    if (second > 60*60*24*30) {
        kill(getpid(), SIGKILL);
        return;
    }
}

#pragma mark - delegate
-(NSInteger)numberOfRowsInTableView:(NSTableView *)tableView{
    return self.selectFileArr.count;
}
-(NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row{
    NSTableCellView* cellView = [tableView makeViewWithIdentifier:tableColumn.identifier owner:self];
    if ([tableColumn.identifier isEqualToString:@"path"]) {
        NSString *filePathStr = [self.selectFileArr objectAtIndex:row];
        cellView.textField.stringValue = filePathStr;
    }else{
        
        NSString *fileUrl = [self.selectFileArr objectAtIndex:row];
        NSString *filePathStr = fileUrl.pathExtension;
        if(filePathStr.length <= 0){
            cellView.textField.stringValue = @"文件夹";
        }else{
            cellView.textField.stringValue = @"0KB";
        }
        
    }
    return cellView;
}
-(void)tableViewSelectionDidChange:(NSNotification *)notification{
    //NSLog(@"selectedRowIndexes : %lu",(unsigned long)self.dragTV.selectedRowIndexes.count);
}

-(BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(NSInteger)row{
    return YES;
}
-(void)tableView:(ZZXDragTV *)tableView dragFilesInToViewComplete:(NSArray<NSURL *> *)files{
    
    for (NSURL *pathUrl in files) {
        NSString *filePath = pathUrl.path;
        [self.selectFileArr addObject:filePath];
    }
    [self.dragTV reloadData];
}
@end
